Skip to content

Fix build errors in mingw #71

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

darksylinc
Copy link
Contributor

Cryptic linking errors would appear when trying to compile with mingw

The errors mentioned __mingw_uuidof,
__mingw_uuidof and __mingw_uuidof as undefined references.

Cryptic linking errors would appear when trying to compile with mingw

The errors mentioned __mingw_uuidof<ID3D12Heap>,
__mingw_uuidof<ID3D12Device8> and __mingw_uuidof<ID3D12Device10> as
undefined references.
@adam-sawicki-a
Copy link
Contributor

Where do these headers come from? Why are they needed? And why not include them always? Is #if !defined(_MSC_VER) the best condition to include them, or should they appear under some dedicated opt-in macro like the existing D3D12MA_D3D12_HEADERS_ALREADY_INCLUDED, D3D12MA_USING_DIRECTX_HEADERS?

I can see "guiddef.h" in the standard Windows SDK, but I can't see "dxguids.h" in either Windows SDK or the DirectX 12 Agility SDK.

@adam-sawicki-a adam-sawicki-a added compatibility Compatibility with some platforms input needed Waiting for more information labels Apr 8, 2025
@darksylinc
Copy link
Contributor Author

Hi!

Why installing from mingw or even native Linux

There are multiple reasons:

  • Cross compiling from Linux to run on Windows.
    • In my case, I prefer to dev on Linux; so I intend to compile the final build on a real Windows machine with MSVC. But in the in the meantime I can catch build errors from Linux instead of going back and forth 2 PCs.
  • Compiling native tools for Linux. e.g. dxc compiler for Linux for servers, compiling Mesa's Vulkan-on-D3D12 for WSL.
  • Compiling from Windows for Windows using mingw. I prefer the MSVC path. But to each, its own.

Header files

  • dxguids.h comes from the official MS DirectX SDK headers. If you're on Ubuntu they can be installed with sudo apt install directx-headers-dev
  • guiddef.h is the one you know, but mingw's flavor which contains definitions needed by dxguids.h

Why are they needed?

Without dxguids.h specifically, D3D12MA will fail because standard mingw headers define at least ID3D12Device8, so D3D12MA will try to use it but it will yield the following linking errors:

/usr/bin/x86_64-w64-mingw32-ld: drivers/d3d12/d3d12ma.windows.editor.dev.x86_64.o: in function `D3D12MA::AllocatorPimpl::Init(D3D12MA::ALLOCATOR_DESC const&)':
/home/matias/SlowProjects/godot/./thirdparty/d3d12ma/D3D12MemAlloc.cpp:6137:(.text+0x867a): undefined reference to `_GUID const& __mingw_uuidof<ID3D12Device1>()'
/usr/bin/x86_64-w64-mingw32-ld: /home/matias/SlowProjects/godot/./thirdparty/d3d12ma/D3D12MemAlloc.cpp:6145:(.text+0x86ee): undefined reference to `_GUID const& __mingw_uuidof<ID3D12Device8>()'
/usr/bin/x86_64-w64-mingw32-ld: /home/matias/SlowProjects/godot/./thirdparty/d3d12ma/D3D12MemAlloc.cpp:6159:(.text+0x8794): undefined reference to `_GUID const& __mingw_uuidof<ID3D12Device10>()'
/usr/bin/x86_64-w64-mingw32-ld: drivers/d3d12/d3d12ma.windows.editor.dev.x86_64.o: in function `D3D12MA::AllocatorPimpl::AllocateHeap(D3D12MA::CommittedAllocationParameters const&, D3D12_RESOURCE_ALLOCATION_INFO const&, bool, void*, D3D12MA::Allocation**)':
/home/matias/SlowProjects/godot/./thirdparty/d3d12ma/D3D12MemAlloc.cpp:7373:(.text+0xc8e7): undefined reference to `_GUID const& __mingw_uuidof<ID3D12Heap>()'
/usr/bin/x86_64-w64-mingw32-ld: /home/matias/SlowProjects/godot/./thirdparty/d3d12ma/D3D12MemAlloc.cpp:7378:(.text+0xc943): undefined reference to `_GUID const& __mingw_uuidof<ID3D12Heap>()'
/usr/bin/x86_64-w64-mingw32-ld: drivers/d3d12/d3d12ma.windows.editor.dev.x86_64.o: in function `D3D12MA::MemoryBlock::Init(ID3D12ProtectedResourceSession*, bool)':
/home/matias/SlowProjects/godot/./thirdparty/d3d12ma/D3D12MemAlloc.cpp:7768:(.text+0xd3d3): undefined reference to `_GUID const& __mingw_uuidof<ID3D12Heap>()'
/usr/bin/x86_64-w64-mingw32-ld: /home/matias/SlowProjects/godot/./thirdparty/d3d12ma/D3D12MemAlloc.cpp:7773:(.text+0xd429): undefined reference to `_GUID const& __mingw_uuidof<ID3D12Heap>()'

This is a cryptic error because it indicates a library is missing, but for some reason a header is what's missing.

And why not include them always?

dxguids.h is only available if using the DirectX Headers, but not the Windows SDK headers.

should they appear under some dedicated opt-in macro like the existing

This is a good question. Since the problem appears with standard mingw headers included in Ubuntu 24.04, IMO ideally this should be autodetected.

Since this path is meant for mingw (i.e. GCC) the header's presence could be detected:

#if !defined(_MSC_VER)
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
#if !__has_include(<dxguids.h>)
#error "mingw or gcc detected. dxguids.h is needed. You can grab it from https://github.com/microsoft/DirectX-Headers or if you're on Ubuntu just run sudo apt install directx-headers-dev"
#endif
#include <guiddef.h>

#include <dxguids.h>
#endif
#endif

But I live that decision up to you.

@adam-sawicki-a adam-sawicki-a merged commit 40f8aa5 into GPUOpen-LibrariesAndSDKs:master Apr 9, 2025
1 check passed
adam-sawicki-a added a commit that referenced this pull request Apr 9, 2025
@adam-sawicki-a
Copy link
Contributor

OK, thank you for this contribution and for the explanation.

@adam-sawicki-a adam-sawicki-a added next release To be done as soon as possible and removed input needed Waiting for more information labels Apr 9, 2025
@oltolm
Copy link

oltolm commented Jun 30, 2025

This commit break building with mingw because dxguids.h is not part of mingw or the Windows SDK. It is also unnecessary because D3D12MemAlloc.cpp compiles without it. Should I create PR to remove it? Why was this PR accepted anyway?

@darksylinc
Copy link
Contributor Author

It is necessary as I explained it.

Without this PR, it will compile but it won't link when compiling from Linux.

dxguid,h is part of the DirectX Headers.

Should I create PR to remove it?

Does this snippet work for you?

#if !defined(_MSC_VER)
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
#if !__has_include(<dxguids.h>)
#error "mingw or gcc detected. dxguids.h is needed. You can grab it from https://github.com/microsoft/DirectX-Headers or if you're on Ubuntu just run sudo apt install directx-headers-dev"
#endif
#include <guiddef.h>

#include <dxguids.h>
#endif
#endif

Does it hit the "#error" block? Does it compile fine?

@oltolm
Copy link

oltolm commented Jun 30, 2025

Yes the snippet compiles fine. I tested using MSYS2 and ucrt64 and clang64 environments.

If I revert this PR then compiling and linking works for me. I don't want to install DirectX headers because it's unnecessary.

If it does not work for you, you need to fix it in your project.

@sawickiap
Copy link
Contributor

I cannot accept a change that uses __has_include because it was added in C++17 while the library declares support for C++14. We may, however, define some macro to be manually defined by the user to correctly support certain platforms if needed. Please feel free to propose necessary changes. I don't have development environment to test it other than Windows + Visual Studio.

@darksylinc
Copy link
Contributor Author

darksylinc commented Jun 30, 2025

I don't think the __has_include() is necessary.

otolm claimed he could compile mingw compiled fine when he added the snippet, which means that __ID3D12Device8_INTERFACE_DEFINED__ was not defined. Therefore #ifdef __ID3D12Device8_INTERFACE_DEFINED__ is enough.

The __has_include() was merely to provide a helpful error message.

Or we could do:

#if !defined(_MSC_VER)
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
#if defined(__has_include)
  #if !__has_include(<dxguids.h>)
    #error "mingw or gcc detected. dxguids.h is needed. You can grab it from https://github.com/microsoft/DirectX-Headers or if you're on Ubuntu just run sudo apt install directx-headers-dev"
  #endif
#endif
#include <guiddef.h>

#include <dxguids.h>
#endif
#endif

Basically if __has_include is supported, we warn the user.
If it isn't, we just go ahead anyway. The important part is being done by __ID3D12Device8_INTERFACE_DEFINED__ macro; since the linking error only appears when using the newer interfaces provided by the Agility SDK.
otolm didn't encounter the problem because he's not using the Agility SDK.

@oltolm
Copy link

oltolm commented Jun 30, 2025

There was a misunderstanding you meant replacing the code with the snippet.

If I do this then I get

[build] FAILED: [code=1] 3rdparty/D3D12MemAlloc/CMakeFiles/D3D12MemAlloc.dir/src/D3D12MemAlloc.cpp.obj 
[build] C:\msys64\clang64\bin\ccache.exe C:\msys64\clang64\bin\clang++.exe -D_HAS_EXCEPTIONS=0 -D_ITERATOR_DEBUG_LEVEL=2 -IC:/src/pcsx2/3rdparty/D3D12MemAlloc/include -g -std=gnu++20 -fansi-escape-codes -fcolor-diagnostics -march=native -pipe -fvisibility=hidden -pthread -fno-exceptions -fsanitize=address -w -MD -MT 3rdparty/D3D12MemAlloc/CMakeFiles/D3D12MemAlloc.dir/src/D3D12MemAlloc.cpp.obj -MF 3rdparty\D3D12MemAlloc\CMakeFiles\D3D12MemAlloc.dir\src\D3D12MemAlloc.cpp.obj.d -o 3rdparty/D3D12MemAlloc/CMakeFiles/D3D12MemAlloc.dir/src/D3D12MemAlloc.cpp.obj -c C:/src/pcsx2/3rdparty/D3D12MemAlloc/src/D3D12MemAlloc.cpp
[build] C:/src/pcsx2/3rdparty/D3D12MemAlloc/src/D3D12MemAlloc.cpp:39:2: error: "mingw or gcc detected. dxguids.h is needed. You can grab it from https://github.com/microsoft/DirectX-Headers or if you're on Ubuntu just run sudo apt install directx-headers-dev"
[build]    39 | #error "mingw or gcc detected. dxguids.h is needed. You can grab it from https://github.com/microsoft/DirectX-Headers or if you're on Ubuntu just run sudo apt install directx-headers-dev"
[build]       |  ^
[build] C:/src/pcsx2/3rdparty/D3D12MemAlloc/src/D3D12MemAlloc.cpp:43:10: fatal error: 'dxguids.h' file not found
[build]    43 | #include <dxguids.h>
[build]       |          ^~~~~~~~~~~
[build] 2 errors generated.

If I revert this PR then the project builds. That is why I am saying that it's unnecessary.

@darksylinc
Copy link
Contributor Author

darksylinc commented Jun 30, 2025

Alternative solution I can think of: This probably got fixed on a newer MINGW version, but now Linux distros will be stuck for a long time due to how LTS releases work.

// On older mingw versions, using the Agility SDK will cause linker errors unless dxguids.h is included.
#if defined( __MINGW64_VERSION_MAJOR ) && defined( __MINGW64_VERSION_MINOR ) && \
    defined( __MINGW64_VERSION_BUGFIX ) && defined( __ID3D12Device8_INTERFACE_DEFINED__ )
#	define D12MA_MAKE_MINGW_VERSION( x, y, z ) ( ( x << 20u ) | ( y << 10u ) | ( z ) )
#	if D12MA_MAKE_MINGW_VERSION( __MINGW64_VERSION_MAJOR, __MINGW64_VERSION_MINOR, \
	                              __MINGW64_VERSION_BUGFIX ) <= D12MA_MAKE_MINGW_VERSION( 11, 0, 1 )
#		if defined( __has_include )
#			if !__has_include( <dxguids.h>)
#				error \
				    "mingw or gcc detected. dxguids.h is needed. You can grab it from https://github.com/microsoft/DirectX-Headers or if you're on Ubuntu just run sudo apt install directx-headers-dev"
#			endif
#		endif
#		include <guiddef.h>

#		include <dxguids.h>
#	endif
#	undef D12MA_MAKE_MINGW_VERSION
#endif

No need to check _MSC_VER anymore because this version looks for mingw-specific macros.

@oltolm can you confirm this compiles for you?

@oltolm
Copy link

oltolm commented Jun 30, 2025

Yes this compiles for me.

@oltolm
Copy link

oltolm commented Jul 8, 2025

Is this going to be fixed? This breaks building on Windows and this is a Windows library. I don't know why it even needs to support Linux.

darksylinc added a commit to darksylinc/D3D12MemoryAllocator that referenced this pull request Jul 9, 2025
This PR incorporates fixes for issues reported in GPUOpen-LibrariesAndSDKs#71
@darksylinc
Copy link
Contributor Author

Opened #77 to fix it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compatibility Compatibility with some platforms next release To be done as soon as possible
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants